#ifndef PLOTVIEW_H
#define PLOTVIEW_H

#include <QResizeEvent>
#include <QWheelEvent>
#include <QMouseEvent>
#include <QPaintEvent>
#include <QKeyEvent>
#include <QWidget>
#include <QPainter>
#include <QLabel>
#include <QPixmap>
#include <QModelIndex>
#include <QMessageBox>

#include "function.h"

class FunctionsModel;

class PlotView : public QWidget
{
    Q_OBJECT
public:
    enum GraphMode {
                None=0,
                Pan,
                Selection};
    PlotView(FunctionsModel* fm = 0,QWidget * parent =0);
    ~PlotView();
    void setModel(FunctionsModel* f) { m_model=f; }

    QSize sizeHint() const { return QSize(100, 100); }

        /** Saves the graphs to a file located at @p path. */
    bool toImage(const QString& path);

        /** Sets whether we will see a grid or only the axes. */
    void setSquares(bool newSquare) { m_squares=newSquare; forceRepaint(); }

        /** Returns whether we have chosen to see the grid. */
    bool squares() const {return m_squares;}

        /** Makes that no function is selected. */
    void unselect();

        /** Sets the graph's viewport to @p v. */
    void setViewport(const QRectF& v);

        /** Sets the desired maximum resolution to @p res. */
    void setResolution(int res);

        /** Returns whether it has a little border frame. */
    bool isFramed() const { return m_framed; }

        /** Sets whether it has a little border frame. */
    void setFramed(bool fr) { m_framed=fr; }

        /** Returns whether it is a read-only widget. */
    bool isReadOnly() const { return m_readonly; }

        /** Sets whether it is a read-only widget. */
    void setReadOnly(bool ro);

        /** Sets whether it has to keep the aspect ratio (1:1 grid). */
    void setKeepAspectRatio(bool ar);

        /** Sets whether it is keeping the aspect ratio (1:1 grid). */
    bool keepAspectRatio() const { return m_keepRatio; }

public slots:
   void forceRepaint() ;

        /** Sets the viewport to a default viewport. */
    void resetViewport(); //

        /** Zooms in to the Viewport center */
    void zoomIn();

        /** Zooms out */
    void zoomOut();

signals:
    void status(const QString &msg);

private slots:
    void update( const QModelIndex & start, const QModelIndex& end );
    void addFuncs( const QModelIndex & parent, int start, int end);
    void removeFuncs( const QModelIndex & parent, int start, int end);

private:
    static const QColor m_axeColor;
    static const QColor m_axe2Color;
    static const QColor m_derivativeColor;

        //painting
    FunctionsModel* m_model;
    QPixmap buffer;
    bool valid;
    QLabel *micepos;
    QPointF mark;
    void drawAxes(QPainter*, function::Axe a);
    void drawPolarAxes(QPainter*);
    void drawCartesianAxes(QPainter*);
    QPointF toWidget(const QPointF &) const;
    QPointF fromWidget(const QPointF& p) const;
    QPointF toViewport(const QPoint& mv) const;
    QPointF calcImage(const QPointF& dp);
    QLineF slope(const QPointF& dp) const;

    QLineF toWidget(const QLineF &) const;

        //events
    void paintEvent( QPaintEvent * );
    void mousePressEvent(QMouseEvent *e);
    void mouseReleaseEvent(QMouseEvent *e);
    void mouseMoveEvent(QMouseEvent *e);
    void keyPressEvent(QKeyEvent * e );
    void wheelEvent(QWheelEvent *e);
    void resizeEvent(QResizeEvent *);
    GraphMode mode;
    QPoint press; QPoint last;

        //presentation
    bool m_squares;
    bool m_keepRatio;
    double resolucio;
    double rang_x, rang_y;
    double rangXDefault,rangYDefault;
    QPointF ant;
    QRectF viewport;
    QRectF userViewport;
    QRectF defViewport;
    void pintafunc(QPaintDevice*);
    void updateScale();

    void sendStatus(const QString& msg) { emit status(msg); }
    bool m_framed;
    bool m_readonly;
    QString m_posText;
    static QRect toBiggerRect(const QRectF&);


};

#endif // PLOTVIEW_H
